package cn.qdhlm.frontendprocessor.common.config;


import cn.qdhlm.frontendprocessor.core.callback.SocketChannelInHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;

/**
 * @Name: SocketServer
 * @Description: 服务端
 * @Author: jiangcs
 */
@Log4j2
@Component
public class SocketServer {
    @Autowired
    private SocketChannelInHandler socketChannelInHandler;
    @Value("${socket.server.port}")
    private Integer socketServerPort;

    /**
     * parentGroup: 用于接收客户端的TCP连接
     */
    private final EventLoopGroup parentGroup = new NioEventLoopGroup();
    /**
     * childGroup: 用于处理I/O相关的读写操作
     */
    private final EventLoopGroup childGroup = new NioEventLoopGroup();
    private Channel channel;
    public void start() {
        log.info("socket server starting...");

        try {
            // ServerBootstrap负责初始化netty服务器，并且开始监听端口的socket请求
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            // 绑定工作线程NioEventLoopGroup
            serverBootstrap.group(parentGroup, childGroup)
                    .channel(NioServerSocketChannel.class)
                    .localAddress(new InetSocketAddress(socketServerPort))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            // 为监听客户端read/write事件的Channel添加用户自定义的ChannelHandler
                            socketChannel.pipeline().addLast(socketChannelInHandler);
                        }
                    });

            // 绑定服务器
            ChannelFuture channelFuture = serverBootstrap.bind().sync();
            if (channelFuture.isSuccess()) {
                channel = channelFuture.channel();

                String address = "未知";
                InetSocketAddress inetSocketAddress = (InetSocketAddress) channel.localAddress();
                if (inetSocketAddress != null) {
                    address = inetSocketAddress.getAddress().getHostAddress() + ":" + inetSocketAddress.getPort();
                }

                log.info("socket server started success: address[{}]", address);
            } else {
                log.error("socket server started error");
            }
        } catch (Exception e) {
            log.error("socket server started exception: ", e);
        }
    }

    /**
     * 停止服务
     */
    public void stop() {
        log.info("socket server stopping...");
        if (channel != null) {
            channel.close();
        }
        parentGroup.shutdownGracefully();
        childGroup.shutdownGracefully();

        // 服务端管道关闭的监听器并同步阻塞,直到channel关闭,线程才会往下执行,结束进程
        channel.closeFuture().syncUninterruptibly();

        log.info("socket server stopped success");
    }
}
